#include <algorithm>
#include <ctype.h>
#include "TcpServer.hpp"
#include "Comm.hpp"
#include <memory>
#include "Translate.hpp"
#include "Daemon.hpp"

Translate trans;
void Usage(std::string proc)
{
    std::cout << "Usage : \n\t" << proc << " local_port\n"
              << std::endl;
}

void Interact(int sockfd , const std::string& out, const std::string& in)
{
    char inbuffer[1024];
    int n = read(sockfd, inbuffer, sizeof(inbuffer) - 1);
    if (n > 0)
    {
        inbuffer[n] = 0;
        write(sockfd, in.c_str(), in.size());
    }
    else if (n == 0)
    {
        lg.LogMessage(Warning, "client quit\n");
    }
    else
    {
        lg.LogMessage(Error, "read failure\n");
    }
}
void Ping(int sockfd, InetAddr &addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd : %d\n", addr.PrintDebug().c_str(), "ping", sockfd);
    std::string message;
    Interact(sockfd,message,"pong");
}
void Translate(int sockfd, InetAddr &addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd : %d\n", addr.PrintDebug().c_str(), "translate", sockfd);
    char word[128];
    int n = read(sockfd,word,sizeof(word));
    std::string chinese = trans.Execut(word);
    write(sockfd,chinese.c_str(),chinese.size());
}
void Transform(int sockfd, InetAddr &addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd : %d\n", addr.PrintDebug().c_str(), "transform", sockfd);
    char buffer[1024];
    read(sockfd,buffer,sizeof(buffer));
    std::string message = buffer;
    std::transform(message.begin(),message.end(),message.begin(),[](char c){
        return std::toupper(c);
    });
    write(sockfd,message.c_str(),message.size());
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(Usage_Err);
    }
    uint16_t port = std::stoi(argv[1]);

    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(port);
    daemon(true,false);
    tsvr->sig_up_task("ping", Ping);
    tsvr->sig_up_task("translate", Translate);
    tsvr->sig_up_task("transform", Transform);

    tsvr->Init();
    tsvr->Start();
    return 0;
}
